package com.hcss.common.interceptor;

import com.hcss.common.base.BaseClass;
import com.hcss.common.constant.CommonConstants;
import com.hcss.common.constant.ConfigConstants;
import com.hcss.common.util.EmptyUtil;
import com.hcss.sys.role.dao.HcSysRoleComplexMapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @描述: 菜单请求拦截
 * @作者: xuqian
 * @创建日期: 2018-08-13 11:21
 * @公司 浙江鸿程计算机系统有限公司
 */
public class URLInterceptor implements HandlerInterceptor {

    private final ConfigConstants configConstants;
    private final HcSysRoleComplexMapper hcSysRoleComplexMapper;

    public URLInterceptor(ConfigConstants configConstants, HcSysRoleComplexMapper hcSysRoleComplexMapper) {
        this.configConstants = configConstants;
        this.hcSysRoleComplexMapper = hcSysRoleComplexMapper;
    }

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        if (configConstants.getWechat().isDebug()) {
            return true;
        }
        if (CommonConstants.XMLHttpRequest.equals(httpServletRequest.getHeader(CommonConstants.XML_HTTP_REQUEST_KEY)) ||
                StringUtils.isNotBlank(httpServletRequest.getHeader(ConfigConstants.MOBILE_HEADER))) {
            return true;
        }
        if (checkURLPermission(httpServletRequest.getServletPath())) {
            return true;
        } else {
            httpServletRequest.getRequestDispatcher(configConstants.getAuth().getUnauthPage()).forward(httpServletRequest, httpServletResponse);
            return false;
        }
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }

    private boolean checkURLPermission(String servletPath) {
        // 未登录走shiro流程
        Object user = SecurityUtils.getSubject().getPrincipal();
        if (EmptyUtil.isHaveEmpty(user)) {
            return true;
        }
        // 校验是否是忽略的链接
        if (checkIgnorUrl(configConstants.getAuth().getIgnoreURL(), servletPath)) {
            return true;
        }
        // 校验是否是角色菜单链接
        List<String> menuUrlList = hcSysRoleComplexMapper.selectMenuUrlByUserid(BaseClass.getSessionUserid());
        return checkMenuUrl(menuUrlList, servletPath);
    }

    /**
     * 校验当前访问链接是否为可忽略的链接
     * @param ignorUrls
     * @param servletPath
     * @return
     */
    private boolean checkIgnorUrl(List<String> ignorUrls, String servletPath) {
        for (String ignorUrl : ignorUrls) {
            if (Pattern.matches("^" + ignorUrl + "$", servletPath)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 校验菜单链接
     * @param menuUrlList
     * @param servletPath
     * @return
     */
    private boolean checkMenuUrl(List<String> menuUrlList, String servletPath) {
        if (menuUrlList.contains(servletPath)) {
            return true;
        }
        for (String menu : menuUrlList) {
            String rmenu = menu.replaceAll("\\*\\*", "\\\\w(/\\\\w)*");
            rmenu = rmenu.replaceAll("\\*", "\\\\w*");
            if (Pattern.matches("^" + rmenu + "$", servletPath)) {
                return true;
            }
        }

        return false;
    }
}
